package com.sservice.service.service;

import com.alibaba.fastjson.JSONObject;
import com.sservice.base.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class Redis {
    private static Logger logger = Logger.getLogger(Redis.class);

    @Autowired
    private RedisTemplate redisTemplate;//

    private RedisTemplate getJedis() {
        return redisTemplate;
    }

    /**
     * 发布消息
     *
     * @param channel 频道
     * @param message 消息
     */
    public void publish(String channel, String message) {
        if (Check.nullOrEmpty(channel) || Check.nullOrEmpty(message)) {
            return;
        }

//        RedisTemplate jedis = getJedis();
//        try {
//            if (jedis != null) {
////                jedis.p(channel, message);
//            }
//        } catch (Exception e) {
//            logger.error(String.format("CALL publish FAIL. Channel:%s, Message:%s, Error: ",
//                    channel, message, e.getMessage()));
//            e.printStackTrace();
//        } finally {
//            R.closeQuietly(jedis);
//        }
    }

    /**
     * 订阅消息
     *
     * @param sub      订阅处理
     * @param channels 频道数组
     */
    public void subscribe(JedisPubSub sub, String... channels) {
//        if (sub == null || Check.nullOrEmpty(channels)) {
//            return;
//        }
//
////        Jedis jedis = getJedis();
//        try {
//            if (redisTemplate != null) {
//                redisTemplate.s(sub, channels);
//            }
//        } catch (Exception e) {
//            logger.error(String.format("CALL subscribe FAIL. Channel:%s, Error: ",
//                    channels, e.getMessage()));
//            e.printStackTrace();
//        } finally {
//            R.closeQuietly(redisTemplate);
//        }
    }

    /**
     * 设置键值过期时间
     *
     * @param key     键值
     * @param seconds 过期时间，单位: 秒
     * @return 操作结果<br>
     * true 操作成功<br>
     * false 操作失败
     */
    public boolean expire(String key, int seconds) {
        if (Check.nullOrEmpty(key) || seconds <= 0) {
            return false;
        }

        if (redisTemplate != null) {
            return redisTemplate.expire(key, seconds, TimeUnit.SECONDS);
        }
        return false;
    }

    /**
     * 返回指定键值剩余过期时间
     *
     * @param key 键值
     * @return 剩余过期时间，单位秒
     */
    public long getExpireTime(String key) {
        if (Check.nullOrEmpty(key)) {
            return -1;
        }


        if (redisTemplate != null) {
            return redisTemplate.getExpire(key);
        }

        return -1;
    }

    public Set<String> keys(String pattern) {
        if (Check.nullOrEmpty(pattern)) {
            return Collections.emptySet();
        }
        if (redisTemplate != null) {
            return redisTemplate.keys(pattern);
        }
        return Collections.emptySet();
    }


    /**
     * 判断KEY是否存在
     *
     * @param key REDIS KEY
     * @return 判断结果<br>
     * true 存在<br>
     * false 不存在<br>
     */
    public boolean existKey(String key) {
        if (Check.nullOrEmpty(key)) {
            return false;
        }
        if (redisTemplate != null) {
            return redisTemplate.hasKey(key);
        }
        return false;
    }

    /**
     * 判断KEY是否存在
     *
     * @param key REDIS KEY
     * @return 判断结果<br>
     * true 存在<br>
     * false 不存在<br>
     */
    public boolean existKey(byte[] key) {
        return !Check.nullOrEmpty(key)
                ? existKey(new String(key))
                : false;
    }

    /**
     * 删除REDIS键值
     *
     * @param key REDIS键值
     * @return 操作结果<br>
     * true 操作成功<br>
     * false 操作失败
     */
    public boolean del(byte[] key) {
        return !Check.nullOrEmpty(key) ? del(new String[]{new String(key)}) : true;
    }

    /**
     * 删除REDIS键值
     *
     * @param key REDIS键值
     * @return 操作结果<br>
     * true 操作成功<br>
     * false 操作失败
     */
    public boolean del(String key) {
        return !Check.nullOrEmpty(key) ? del(new String[]{key}) : true;
    }

    /**
     * 删除REDIS键值
     *
     * @param keys REDIS键值数组
     * @return 操作结果<br>
     * true 操作成功<br>
     * false 操作失败
     */
    public boolean del(String[] keys) {
        if (Check.nullOrEmpty(keys)) {
            return true;
        }
        redisTemplate.delete(keys);
        return false;
    }

    /**
     * 删除REDIS键值
     *
     * @param keys REDIS键值集合
     * @return 操作结果<br>
     * true 操作成功<br>
     * false 操作失败
     */
    public boolean del(Collection<String> keys) {
        return !Check.nullOrEmpty(keys) ? del(keys.toArray(new String[]{})) : false;
    }

    public String get(String key) {
        if (Check.nullOrEmpty(key)) {
            return "";
        }
        Object obj = redisTemplate.opsForValue().get(key);
        return obj != null ? obj.toString() : "";
    }

    /**
     * set obj by key
     *
     * @param key
     * @param value
     * @return
     */
    public boolean setObj(String key, Object value) {
        return set(key, JSONObject.toJSONString(value));
    }

    /**
     * get obj by key
     *
     * @param key
     * @return
     */
    public JSONObject getObj(String key) {
        String str = get(key);
        if (StringUtils.isNoneBlank(str)) {
            return JSONObject.parseObject(str);
        }
        return null;
    }

    public boolean set(String key, String value) {

        redisTemplate.opsForValue().set(key, value);
        return true;
    }

    public long incr(String key) {
        if (Check.nullOrEmpty(key)) {
            return 0L;
        }

        return 0L;
    }

    public long incrBy(String key, long value) {
        if (Check.nullOrEmpty(key)) {
            return 0L;
        }
        return redisTemplate.opsForValue().increment(key, value);
    }

    public long hincrBy(String key, String field, long value) {
        if (Check.nullOrEmpty(key) || Check.nullOrEmpty(field)) {
            return 0L;
        }

        return redisTemplate.opsForHash().increment(key, field, value);
    }

    public long decr(String key) {


        return Long.MIN_VALUE;
    }

    public long decrBy(String key, long value) {
        if (Check.nullOrEmpty(key)) {
            return Long.MIN_VALUE;
        }

        return redisTemplate.opsForValue().increment(key, value);
    }

    public boolean lpush(String key, Collection<String> values) {
//        if (key == null || key.trim().length() == 0
//                || values == null || values.size() == 0) {
//            return false;
//        }
//
//
//        Pipeline pipeline = null;
//        try {
//            if (redisTemplate != null) {
//                pipeline = redisTemplate.pipelined();
//                pipeline.lpush(key, values.toArray(new String[0]));
//                pipeline.sync();
//
//                return true;
//            }
//        } catch (Exception e) {
//            logger.error("CALL lpush FAIL. Error: " + e.getMessage());
//            e.printStackTrace();
//        } finally {
//            if (pipeline != null) {
//                pipeline.clear();
//            }
//
//            R.closeQuietly(pipeline);
//            R.closeQuietly(jedis);
//        }

        return false;
    }

    public boolean lpush(String key, String value) {
        return lpush(key, Arrays.asList(value));
    }

    public boolean lpush(byte[] key, Collection<byte[]> values) {
//        if (Check.nullOrEmpty(key) || Check.nullOrEmpty(values)) {
//            return false;
//        }
//
//        Jedis jedis = getJedis();
//
//        Pipeline pipeline = null;
//        try {
//            if (jedis != null) {
//                pipeline = jedis.pipelined();
//
//                byte[][] bs = new byte[values.size()][];
//
//                int i = 0;
//                for (byte[] data : values) {
//                    if (data != null) {
//                        bs[i] = data;
//                        i++;
//                    }
//                }
//
//                pipeline.lpush(key, bs);
//                pipeline.sync();
//
//                return true;
//            }
//        } catch (Exception e) {
//            logger.error("CALL lpush FAIL. Error: " + e.getMessage());
//            e.printStackTrace();
//        } finally {
//            if (pipeline != null) {
//                pipeline.clear();
//            }
//
//            R.closeQuietly(pipeline);
//            R.closeQuietly(jedis);
//        }

        return false;
    }

    public boolean lpush(byte[] key, byte[] value) {
        return lpush(key, value != null ? Arrays.asList(value) : null);
    }

    public boolean lpush(Map<byte[], byte[]> map) {
//        if (Check.nullOrEmpty(map)) {
//            return false;
//        }
//
//        Jedis jedis = getJedis();
//        Pipeline pipeline = null;
//        try {
//            if (jedis != null) {
//                pipeline = jedis.pipelined();
//                for (byte[] key : map.keySet()) {
//                    pipeline.lpush(key, map.get(key));
//                }
//                pipeline.sync();
//
//                return true;
//            }
//        } catch (Exception e) {
//            logger.error("CALL lpush FAIL. Error: " + e.getMessage());
//            e.printStackTrace();
//        } finally {
//            if (pipeline != null) {
//                pipeline.clear();
//            }
//
//            R.closeQuietly(pipeline);
//            R.closeQuietly(jedis);
//        }

        return false;
    }

    public List<byte[]> lpop(byte[] key, int size) {
//        if (Check.nullOrEmpty(key) || size <= 0) {
//            return Collections.emptyList();
//        }
//
//        Jedis jedis = getJedis();
//        Pipeline pipe = null;
//        try {
//            if (jedis != null) {
//                if (!jedis.exists(key)) {
//                    return Collections.emptyList();
//                }
//
//                pipe = jedis.pipelined();
//
//                List<Response<byte[]>> rsps = new LinkedList<>();
//                for (int i = 0; i < size; i++) {
//                    Response<byte[]> rsp = pipe.lpop(key);
//                    if (rsp == null) {
//                        break;
//                    }
//
//                    rsps.add(rsp);
//                }
//                pipe.sync();
//
//                List<byte[]> list = new LinkedList<>();
//                for (Response<byte[]> r : rsps) {
//                    byte[] arr = r.get();
//                    if (arr == null || arr.length == 0) {
//                        break;
//                    }
//
//                    list.add(arr);
//                }
//
//                return list;
//            }
//        } catch (Exception e) {
//            logger.error("CALL lpush FAIL. Error: " + e.getMessage());
//            e.printStackTrace();
//        } finally {
//            if (pipe != null) {
//                pipe.clear();
//            }
//
//            R.closeQuietly(pipe);
//            R.closeQuietly(jedis);
//        }

        return Collections.emptyList();
    }

    public byte[] lpop(byte[] key) {
        List<byte[]> list = lpop(key, 1);
        return !Check.nullOrEmpty(list) ? list.get(0) : null;
    }

    public List<String> lpop(String key, int size) {
//        if (Check.nullOrEmpty(key) || size <= 0) {
//            return Collections.emptyList();
//        }
//
//        Jedis jedis = getJedis();
//        Pipeline pipe = null;
//        try {
//            if (jedis != null) {
//                if (!jedis.exists(key)) {
//                    return Collections.emptyList();
//                }
//
//                pipe = jedis.pipelined();
//
//                List<Response<String>> response = new LinkedList<>();
//                for (int i = 0; i < size; i++) {
//                    Response<String> rsp = pipe.lpop(key);
//                    if (rsp == null) {
//                        break;
//                    }
//                    response.add(rsp);
//                }
//                pipe.sync();
//
//                List<String> list = new LinkedList<>();
//                for (Response<String> r : response) {
//                    String s = r.get();
//                    if (s == null || s.equalsIgnoreCase("")) {
//                        break;
//                    }
//                    list.add(s);
//                }
//
//                return list;
//            }
//        } catch (Exception e) {
//            logger.error("CALL lpop FAIL. Error: " + e.getMessage());
//            e.printStackTrace();
//        } finally {
//            if (pipe != null) {
//                pipe.clear();
//            }
//
//            R.closeQuietly(pipe);
//            R.closeQuietly(jedis);
//        }

        return Collections.emptyList();
    }

    public String lpop(String key) {
        List<String> list = lpop(key, 1);
        return list == null || list.size() == 0 ? "" : list.get(0);
    }

    public List<String> lrange(String key, long start, long end) {
//        if (Check.nullOrEmpty(key)) {
//            return Collections.emptyList();
//        }
//
//        Jedis jedis = getJedis();
//        try {
//            if (jedis != null) {
//                List<String> result = jedis.lrange(key, start, end);
//                return result != null ? result : Collections.emptyList();
//            }
//        } catch (Exception e) {
//            logger.error("CALL lrange FAIL. Error: " + e.getMessage());
//            e.printStackTrace();
//        } finally {
//            R.closeQuietly(jedis);
//        }

        return Collections.emptyList();
    }

    public List<byte[]> lrange(byte[] key, long start, long end) {
//        if (Check.nullOrEmpty(key)) {
//            return Collections.emptyList();
//        }
//
//        Jedis jedis = getJedis();
//        try {
//            if (jedis != null) {
//                List<byte[]> result = jedis.lrange(key, start, end);
//                return result != null ? result : Collections.emptyList();
//            }
//        } catch (Exception e) {
//            logger.error("CALL lrange FAIL. Error: " + e.getMessage());
//            e.printStackTrace();
//        } finally {
//            R.closeQuietly(jedis);
//        }

        return Collections.emptyList();
    }

    /**
     * 获取列表长度
     *
     * @param key 键值
     * @return 列表长度
     */
    public long llen(String key) {
//        if (Check.nullOrEmpty(key)) {
//            return 0;
//        }
//
//        Jedis jedis = getJedis();
//        try {
//            if (jedis != null) {
//                Long v = jedis.llen(key);
//                return v != null ? v.longValue() : 0;
//            }
//        } catch (Exception e) {
//            logger.error("CALL existKey FAIL. Error: " + e.getMessage());
//            e.printStackTrace();
//        } finally {
//            R.closeQuietly(jedis);
//        }

        return 0;
    }

    public List<byte[]> rpop(byte[] key, int size) {
//        if (Check.nullOrEmpty(key) || size <= 0) {
//            return Collections.emptyList();
//        }
//
//        Jedis jedis = getJedis();
//        Pipeline pipe = null;
//
//        List<byte[]> list = new LinkedList<>();
//        List<Response<byte[]>> rsps = new LinkedList<>();
//        try {
//            if (jedis != null) {
//                if (!jedis.exists(key)) {
//                    return Collections.emptyList();
//                }
//
//                pipe = jedis.pipelined();
//                for (int i = 0; i < size; i++) {
//                    Response<byte[]> rsp = pipe.rpop(key);
//                    if (rsp == null) {
//                        break;
//                    }
//                    rsps.add(rsp);
//                }
//                pipe.sync();
//
//                for (Response<byte[]> r : rsps) {
//                    byte[] arr = r.get();
//                    if (arr == null || arr.length == 0) {
//                        break;
//                    }
//                    list.add(arr);
//                }
//            }
//        } catch (Exception e) {
//            logger.error("CALL rpop FAIL. Error: " + e.getMessage());
//            e.printStackTrace();
//        } finally {
//            R.closeQuietly(pipe);
//            R.closeQuietly(jedis);
//        }

        return null;
    }

    public boolean hmset(String key, Map<String, String> map) {
//        if (Check.nullOrEmpty(key) || Check.nullOrEmpty(map)) {
//            return false;
//        }
//
//        Jedis jedis = getJedis();
//        try {
//            if (jedis != null) {
//                return jedis.hmset(key, map).equalsIgnoreCase("OK");
//            }
//        } catch (Exception e) {
//            logger.error("CALL hmset FAIL. Error: " + e.getMessage());
//            e.printStackTrace();
//        } finally {
//            R.closeQuietly(jedis);
//        }

        return false;
    }

    public List<String> hmget(String key, List<String> fields) {
//        if (Check.nullOrEmpty(key) || Check.nullOrEmpty(fields)) {
//            return Collections.emptyList();
//        }
//
//        Jedis jedis = getJedis();
//        try {
//            if (jedis != null) {
//                return jedis.hmget(key, fields.toArray(new String[0]));
//            }
//        } catch (Exception e) {
//            logger.error("CALL hmget FAIL. Error: " + e.getMessage());
//            e.printStackTrace();
//        } finally {
//            R.closeQuietly(jedis);
//        }

        return Collections.emptyList();
    }

    public boolean hset(String key, String field, String value) {
//        if (Check.nullOrEmpty(key) || Check.nullOrEmpty(field)) {
//            return false;
//        }
//
//        Jedis jedis = getJedis();
//
//        try {
//            if (jedis != null) {
//                return jedis.hset(key, field, value) > 0;
//            }
//        } catch (Exception e) {
//            logger.error("CALL hset FAIL. Error: " + e.getMessage());
//            e.printStackTrace();
//        } finally {
//            R.closeQuietly(jedis);
//        }

        return false;

    }

    public String hget(String key, String field) {
////        if (Check.nullOrEmpty(key) || Check.nullOrEmpty(field)) {
////            return "";
////        }
////
////        String value = null;
////
////        Jedis jedis = getJedis();
////        try {
////            if (jedis != null) {
////                value = jedis.hget(key, field);
////            }
////        } catch (Exception e) {
////            logger.error("CALL hget FAIL. Error: " + e.getMessage());
////            e.printStackTrace();
////        } finally {
////            R.closeQuietly(jedis);
////        }
//
//        return value != null ? value : "";
        return  null;
    }

    public Map<String, String> hgets(String key, String[] fields) {
//        if (Check.nullOrEmpty(key) || Check.nullOrEmpty(fields)) {
//            return Collections.emptyMap();
//        }
//
//        Jedis jedis = getJedis();
//        try {
//            if (jedis != null) {
//                List<String> values = jedis.hmget(key, fields);
//                if (values != null && values.size() == fields.length) {
//                    Map<String, String> map = new LinkedHashMap<>();
//                    for (int i = 0; i < fields.length; i++) {
//                        map.put(fields[i], values.get(i));
//                    }
//
//                    return map;
//                }
//            }
//        } catch (Exception e) {
//            logger.error("CALL hget FAIL. Error: " + e.getMessage());
//            e.printStackTrace();
//        } finally {
//            R.closeQuietly(jedis);
//        }

        return Collections.emptyMap();
    }

    public Map<String, String> hgetAll(String key) {
//        if (Check.nullOrEmpty(key)) {
//            return Collections.emptyMap();
//        }
//
//        Jedis jedis = getJedis();
//        try {
//            if (jedis != null) {
//                return jedis.hgetAll(key);
//            }
//        } catch (Exception e) {
//            logger.error("CALL hgetall FAIL. Error: " + e.getMessage());
//            e.printStackTrace();
//        } finally {
//            R.closeQuietly(jedis);
//        }

        return Collections.emptyMap();
    }

}